using System;
using System.Collections;
using System.Collections.Generic;
using LitJson;
using Sirenix.Utilities;
using System.Linq;

#if UNITY_EDITOR
using System.Reflection;
using OfficeOpenXml;
using UnityEditor;
#endif

using Sirenix.OdinInspector;
using UnityEngine;

namespace MetaTable
{
    [Serializable]
    public abstract partial class MetaTableBase : IMetaTableBase
    {
        public int Priority = 0;

        public abstract string TableName { get; }

        public abstract IMetaTableRow GetMetaTableRowByUuid(string uuid);

        public abstract IReadOnlyList<IMetaTableRow> BaseRows { get; }

        public abstract void AddRows(IReadOnlyList<IMetaTableRow> rows);

        public abstract void MergeRows(IReadOnlyList<IMetaTableRow> rows);

        public abstract Type RowType { get; }

    }

    public abstract class MetaTableBase<T> : MetaTableBase where T : class, IMetaTableRow
    {
        public override Type RowType => typeof(T);

        public readonly Dictionary<string, T> RowDict = new Dictionary<string, T>();

        public override IReadOnlyList<IMetaTableRow> BaseRows => RowDict.Values.ToList() as IReadOnlyList<IMetaTableRow>;

        public override void AddRows(IReadOnlyList<IMetaTableRow> rows)
        {
            for (int i = 0; i < rows.Count; i++)
            {
                var o = rows[i];
                if (o.Uuid == null)
                {
                    Debug.LogError("AddRows Uuid Is Null");
                    return;
                }
                if (RowDict.ContainsKey(o.Uuid))
                {
                    Debug.LogError($"{GetType().Name} Uuid:{o.Uuid} Dup! Please Check");
                    return;
                }
                RowDict.Add(o.Uuid, o as T);
            }
        }

        public override void MergeRows(IReadOnlyList<IMetaTableRow> rows)
        {
            for (int i = 0; i < rows.Count; i++)
            {
                if (!RowDict.ContainsKey(rows[i].Uuid))
                {
                    RowDict.Add(rows[i].Uuid, rows[i] as T);
                }
            }
        }

        public T GetRowByUuid(string uuid)
        {
            if (RowDict.TryGetValue(uuid, out T row))
            {
                return row;
            }
            return null;
        }

        public override IMetaTableRow GetMetaTableRowByUuid(string uuid)
        {
            return GetRowByUuid(uuid);
        }

    }

}
